//只负责光照计算
Shader "DRText2"
{
    Properties
    {

    }
    SubShader
    {
		ZWrite Off
		//LDR Blend DstColor Zero    HDR : Blend One One
		Blend one one     
        Pass
        {

            CGPROGRAM
			#pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag
			#pragma multi_compile_lightpass
			//代表排除不支持MRT的硬件
			// #pragma exclude_renderers norm
			#pragma multi_compile __ UNITY_HDR_ON

			#include "UnityCG.cginc"
			#include "UnityDeferredLibrary.cginc"
			#include "UnityPBSLighting.cginc"
			#include "./FxLibrary.cginc"


			sampler2D _CameraGBufferTexture0;
			sampler2D _CameraGBufferTexture1;
			sampler2D _CameraGBufferTexture2;
			sampler2D _CameraGBufferTexture3;
            float _LightSwitch;
            //sampler2D _ShadowMapTexture;
            
			//float4 _LightColor, _LightDir,_LightPos;
			

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal :NORMAL;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float4 uv :TEXCOORD0;
				float3 ray : TEXCOORD1;
				
			};


			// float3 DepthToWorldPositionV1(float2 screenPos)
			// {
			//     //screenPos / screenPos.w就是【0,1】的归一化屏幕坐标  //_CameraDepthTexture是获取的深度图
			//     //Linear01Depth将采样的非线性深度图变成线性的
			//     float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
			// 	depth = Linear01Depth(depth);
			//     //将【0，1】映射到【-1， 1】上，得到ndcPos的x，y坐标
			//     float2 ndcPosXY = screenPos * 2 - 1;
			//     //float3的z值补了一个1，代表远平面的NDC坐标  _ProjectionParams代表view空间的远平面, 我们知道裁剪空间的w和view空间的z相等，
			//     //相当于做了一次逆向透视除法，得到了远平面的clipPos
			//     float3 clipPos = float3(ndcPosXY.x, ndcPosXY.y, 1) * _ProjectionParams.z;
			//
			//     float3 viewPos = mul(unity_CameraInvProjection, clipPos.xyzz).xyz * depth;  //远平面的clipPos转回远平面的viewPos， 再利用depth获取该点在viewPos里真正的位置
			//     //补一个1变成其次坐标，然后逆的V矩阵变回worldPos
			//     float3 worldPos = mul(UNITY_MATRIX_I_V, float4(viewPos, 1)).xyz;
			//     return worldPos;
			// }

			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = ComputeScreenPos(o.pos);
				o.ray = UnityObjectToViewPos(v.vertex)*float3(-1,-1,1);
				//_LightAsQuad  当在处理四边形时，也就是直射光时返回1，否则返回0
				o.ray = lerp(o.ray, v.normal, _LightAsQuad);
				//o.ray = v.normal;
				return o;
			}


			fixed4 frag(v2f i) : SV_Target
			{
				//拿资源
				
				float3 lDirWS = -_LightDir.xyz;
				float2 uv=i.uv.xy/i.uv.w;
				half4 gbuffer0 = tex2D(_CameraGBufferTexture0, uv);
				half4 gbuffer1 = tex2D(_CameraGBufferTexture1, uv);
				half4 gbuffer2 = tex2D(_CameraGBufferTexture2, uv);

				//深度图重构世界空间坐标（尝试射线法）
				float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
				depth = Linear01Depth(depth);
				float3 rayToFarPlane = i.ray * _ProjectionParams.z / i.ray.z;
				float3 PosVS = rayToFarPlane * depth;
				//float3 posWS_Re1 = DepthToWorldPositionV1(uv); 
	            float3 posWS = mul(unity_CameraToWorld, float4(PosVS, 1)).xyz;


				
				
				//拿数据
				half3 diffuseColor = gbuffer0.rgb;
				half3 specularColor = gbuffer1.rgb;
				//float gloss = gbuffer1.a * 50;
				float3 nDirWS = normalize(gbuffer2.xyz * 2 - 1);
				float3 vDirWS = normalize(UnityWorldSpaceViewDir(posWS));
				float3 hDirWS = normalize(lDirWS + vDirWS);
				float3 nDirVS = normalize(mul(UNITY_MATRIX_V,nDirWS));
				float nDotL = max(0.0,dot(nDirWS,lDirWS));
				float Roughness = 1-gbuffer1.a;
				float shadowAttenuation = 1;
				bool shadowed = false;

				


			     #if defined(DIRECTIONAL) || defined(DIRECTIONAL_COOKIE)
                    #ifdef SHADOWS_SCREEN
                        shadowed =true;
                        //阴影采样
                        shadowAttenuation=tex2D(_ShadowMapTexture,uv).r;
                    #endif
	            #else
	                //聚光点光有位置，所以重新计算光源方向，_LightPos也要自己定义好
	                float3 lightVec = _LightPos.xyz - posWS;
                    #if defined(SPOT)
                        #if defined(SHADOWS_DEPTH)
                        //聚光灯阴影
				        shadowed =true;
                        shadowAttenuation = UnitySampleShadowmap(mul(unity_WorldToShadow[0], float4(posWS, 1)));
                        #endif
                    #else

                        #if defined(SHADOWS_CUBE)
                        //点光源阴影
				        shadowed =true;
                        shadowAttenuation = UnitySampleShadowmap(-lightVec);
                        #endif
                    
                    #endif
 
	            #endif
	            
	             if(shadowed){
	                 //阴影距离渐变 (Shadow Distance)
                     float shadowFadeDistance =UnityComputeShadowFadeDistance(posWS, PosVS);
                     float shadowFade = UnityComputeShadowFade(shadowFadeDistance); 
                     shadowAttenuation=saturate(shadowAttenuation+shadowFade);
                     #if defined(UNITY_FAST_COHERENT_DYNAMIC_BRANCHING) && defined(SHADOWS_SOFT)
                         UNITY_BRANCH
                         if (shadowFade > 0.99) {
                         shadowAttenuation = 1;
                         }
                     #endif
	             }



				float3 color = float3(0,0,0);

				// 判断是平行光还是点光源
	            if (_LightAsQuad== 1.0)
	            {
	            	
					//尝试还原PBR
					float3 diffuse = diffuseColor;
					diffuse = diffuse*_LightColor.rgb*max(dot(nDirWS, lDirWS), 0.0);
					//镜面反射项
					//D
	                float D = DistributionGGX(nDirWS,hDirWS,Roughness);
	                //Geometry 几何函数
	                float G = GeometrySmith(nDirWS, vDirWS, lDirWS, Roughness);
					//混合——镜面
	                float3 nominator    = D * G * gbuffer1.rgb;
	                float denominator = 4.0 * max(dot(nDirWS, vDirWS), 0.0) * max(dot(nDirWS, lDirWS), 0.0) + 0.001;
	                float3 Specular     = nominator / denominator;
					Specular = Specular*max(nDotL,0.00001)*_LightColor.rgb*UNITY_PI;
					float3 rgb = (diffuse+Specular)*shadowAttenuation;
	            	color = rgb;
	            }
	            else
	            {
	            	lDirWS =normalize(_LightPos.xyz-posWS);
	            	hDirWS = normalize(lDirWS + vDirWS);
	            	nDotL = max(0.0,dot(nDirWS,lDirWS));
	            	float attenuation = tex2D(_LightTextureB0,(dot((_LightPos.xyz-posWS), (_LightPos.xyz-posWS)) * _LightPos.w).rr).UNITY_ATTEN_CHANNEL;
	            	//尝试还原PBR
					float3 diffuse = diffuseColor;
	            	float3 t = max(dot(nDirWS, lDirWS), 0.0);
					diffuse = diffuse*_LightColor.rgb*max(dot(nDirWS, lDirWS), 0.0);
					//镜面反射项
					//D
	                float D = DistributionGGX(nDirWS,hDirWS,Roughness);
	                //Geometry 几何函数
	                float G = GeometrySmith(nDirWS, vDirWS, lDirWS, Roughness);
					//混合——镜面
	                float3 nominator    = D * G * gbuffer1.rgb;
	                float denominator = 4.0 * max(dot(nDirWS, vDirWS), 0.0) * max(dot(nDirWS, lDirWS), 0.0) + 0.001;
	                float3 Specular     = nominator / denominator;
					Specular = Specular*max(dot(nDirWS, lDirWS),0.00001)*_LightColor.rgb*UNITY_PI;
	                float2 OffectSamplePos = uv+nDirVS.xy*0.02*0.1;
	                float offsetDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,uv);
	                float trueDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,OffectSamplePos);
	                float linear01EyeOffecDepth = LinearEyeDepth(offsetDepth);
	                float linear01EyeTrueDepth = LinearEyeDepth(trueDepth);
	                float depthDiffer = linear01EyeTrueDepth - linear01EyeOffecDepth;
	            	//nDotL = nDotL<0.5?0:nDotL;
	                float3 rimlight = min(1,lerp(0,1,depthDiffer))*_LightColor.rgb*nDotL;
	            	//rimlight = lerp(0,rimlight,));
	            	float3 rgb = diffuse+Specular;
	            	rgb= shadowAttenuation*attenuation*(rgb+rimlight);
	            	color = rgb;
	            }
				color = lerp(color,diffuseColor,_LightSwitch);
			    //return float4(color,1);
				return float4(color,1);
			}
            ENDCG
        }

		
		//转码pass，主要是对于LDR转码
		Pass 
		{
			ZTest Always
			Cull Off
			ZWrite Off
			Stencil
			{
				Ref[_StencilNonBackGround]
				ReadMask[_StencilNonBackground]

				CompBack equal
				CompFront equal
			}

			CGPROGRAM
			#pragma target 3.0
			#pragma vertex vert
			#pragma fragment frag
			#pragma exclude_renderers nomrt

			#include "UnityCG.cginc"

			sampler2D _LightBuffer;
			struct v2f
			{
				float4 vertex:SV_POSITION;
				float2 texcoord: TEXCOORD0;
			};

			v2f vert(float4 vertex:POSITION,float2 texcoord :TEXCOORD0)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(vertex);
				o.texcoord = texcoord.xy;
				#ifdef UNITY_SINGLE_PASS_STEREO
				o.texcoord = TransformStereoScreenSpaceTex(o.texcoord,1.0);
				#endif
				return o;
			}

			fixed4 frag(v2f i) :SV_Target
			{
				return -log2(tex2D(_LightBuffer,i.texcoord));
			}
			ENDCG
		}
    }
}